import  { defineStore } from  'pinia'
import {store} from "/@/store";
import {UserInfo} from "/#/store";
import {getAuthCache, setAuthCache} from "/@/utils/auth";
import {CacheKeyEnum} from "/@/enums/CacheEnum";
import {GetUserInfoModel, LoginParams} from "/@/api/sys/model/userModel";
import {ErrorMessageMode} from "/#/axios";
import {doLogout, getUserInfo, loginApi} from "/@/api/sys/user";
import {isArray} from "/@/utils/is";
import {PAGE_NOT_FOUND_ROUTE} from "/@/router/basis";
import {router} from "/@/router";
import {RouteRecordRaw} from "vue-router";
import {PageEnum} from "/@/enums/pageEnum";
import {usePermissionStore, usePermissionStoreWithOut} from "/@/store/modules/permission";
import {h} from "vue";
import {useMessage} from "/@/hooks/web/useMessage";

interface UserState {
    userInfo: UserInfo | null;
    token?: string;
    roleList: string[];
}

export const useUserStore = defineStore({
    id: 'app-user',
    state: (): UserState => ({
        // user info
        userInfo: null,
        // token
        token: undefined,
        // roleList
        roleList: [],
    }),
    getters: {
        getUserInfo(): UserInfo| null {
            return this.userInfo || getAuthCache(CacheKeyEnum.USER_INFO) || {};
        },
        getToken(): string {
            return this.token || getAuthCache(CacheKeyEnum.TOKEN);
        },
        getRoleList(): string[] {
            return this.roleList.length > 0 ? this.roleList : (getAuthCache(CacheKeyEnum.ROLE_LIST) || []);
        },
    },
    actions: {
        setToken(info: string | undefined) {
            this.token = info ? info : ''; // for null or undefined value
            setAuthCache(CacheKeyEnum.TOKEN, info);
        },
        setRoleList(roleList: string[]) {
            this.roleList = roleList;
            setAuthCache(CacheKeyEnum.ROLE_LIST, roleList);
        },
        setUserInfo(info: UserInfo | null) {
            this.userInfo = info;
            setAuthCache(CacheKeyEnum.USER_INFO, info);
        },
        resetState() {
            this.userInfo = null;
            this.token = '';
            this.roleList = [];
        },
        /**
         * @description: login
         */
        async login(
            params: LoginParams & {
                goHome?: boolean;
                mode?: ErrorMessageMode;
            },
        ): Promise<GetUserInfoModel | null> {
            try {
                const { goHome = true, mode, ...loginParams } = params;
                const data = await loginApi(loginParams, mode);
                const { token } = data;
                // save token
                this.setToken(token);
                return this.afterLoginAction(goHome);
            } catch (error) {
                return Promise.reject(error);
            }
        },
        async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {
            if (!this.getToken) return null;
            // get user info
            const userInfo = await this.getUserInfoAction();
            const permissionStore = usePermissionStore();
            if (!permissionStore.isDynamicAddedRoute) {
                const routes = await permissionStore.buildRoutesAction();
                routes?.forEach((route:any) => {
                    router.addRoute(route as unknown as RouteRecordRaw);
                });
                router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
                permissionStore.setDynamicAddedRoute(true);
            }
            goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME));
            return userInfo;
        },
        async getUserInfoAction(): Promise<GetUserInfoModel | null> {
            if (!this.getToken) return null;
            const userInfo = await getUserInfo();
            const { roles = [] } = userInfo;
            if (isArray(roles)) {
                const roleList = roles.map((item) => item.value);
                this.setRoleList(roleList as []);
            } else {
                userInfo.roles = [];
                this.setRoleList([]);
            }
            this.setUserInfo(userInfo as UserInfo);
            return userInfo;
        },
        /**
         * @description: logout
         */
        async logout(goLogin = false) {
            const permissionStoreWithOut = usePermissionStoreWithOut();
            if (this.getToken) {
                try {
                    await doLogout();
                } catch {
                    console.log('注销Token失败');
                }
            }
            this.setToken(undefined);
            this.setUserInfo(null);
            this.setRoleList([]);
            permissionStoreWithOut.resetState();
            goLogin && router.push(PageEnum.BASE_LOGIN);
        },

        /**
         * @description: Confirm before logging out
         */
        confirmLoginOut() {
            const { createConfirm } = useMessage();
            createConfirm({
                iconType: 'warning',
                title: () => h('span', '登出提示'),
                content: () => h('span', '你确定要退出登录吗？'),
                okText: '退出登录',
                cancelText: '取消',
                onOk: async () => {
                    await this.logout(true);
                },
            });
        }

    },
});

// Need to be used outside the setup
export function useUserStoreWithOut() {
    return useUserStore(store);
}


